package com.daxt.controller.infomanager;

import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.daxt.base.common.util.RedisUtil;
import com.daxt.common.annotations.LoginAuth;
import com.daxt.common.annotations.LoginUser;
import com.daxt.common.exception.BaseException;
import com.daxt.common.util.DateUtil;
import com.daxt.mapper.archives.ArchivesDurableFileMapper;
import com.daxt.mapper.sys.ArchivesTypeMapper;
import com.daxt.model.constant.BaseConstants;
import com.daxt.model.dic.*;
import com.daxt.model.search.ArchivesSearch;
import com.daxt.model.service.archives.vo.*;
import com.daxt.model.service.base.result.UserInfo;
import com.daxt.service.ArchivesBehaveLogService;
import com.daxt.service.ArchivesService;
import com.daxt.utils.BaseUtil;
import com.daxt.utils.LocalDateTimeUtil;
import com.daxt.utils.ZipUtil;
import com.daxt.utils.file.FileBaseUtil;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.daxt.common.result.Result;
import com.daxt.common.result.ResultCode;
import com.daxt.common.result.ResultUtil;
import com.daxt.mapper.archives.ArchivesDocMapper;
import com.daxt.model.service.archives.param.SetStateParam;
import com.daxt.model.service.archives.result.ArchivesList;
import com.daxt.service.DocService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Api(tags = "归档审批整理")
@RestController
@RequestMapping("/infoManager")
public class ArchivesController {

    @Autowired
    private ArchivesDocMapper archivesDocMapper;
    @Autowired
    private DocService docService;
    @Autowired
    private ArchivesService archivesService;
    @Autowired
    private ArchivesTypeMapper archivesTypeMapper;
    @Autowired
    private ArchivesDurableFileMapper archivesDurableFileMapper;
    @Autowired
    private ArchivesBehaveLogService archivesBehaveLogService;

    @ApiOperation(value = "下载持久化文件", notes = "")
    @PostMapping("/durable")
    public void downDurable(@RequestBody SetStateParam setStateParam,HttpServletResponse response){

        ArchivesType at = archivesTypeMapper.selectById(Long.parseLong(setStateParam.getTypeId()));
        if (null == at || "0".equals(at.getAutoDurableFile())) {
            throw new BaseException("1001","请开启持久化文件配置");
        }

        try {
            String tempPath = RedisUtil.getSysConfig(SystemConfigType.TEMP_PATH);
            QueryWrapper<ArchivesDurableFile> durableFileQueryWrapper=new QueryWrapper<>();
            durableFileQueryWrapper.in("docId",setStateParam.getIds());
            List<ArchivesDurableFile> durableFileList = archivesDurableFileMapper.selectList(durableFileQueryWrapper);

            StringBuilder outFileStr=new StringBuilder();
            outFileStr.append(tempPath);

            //System.out.println("durableFileList.size()："+durableFileList.size());

            if(!durableFileList.isEmpty() && durableFileList.size() == 1){
                ArchivesDurableFile durableFile = durableFileList.get(0);

                String fileUrl=durableFile.getFileUrl();
                String itemNum = fileUrl.substring(fileUrl.lastIndexOf("/")+1);
                outFileStr.append(itemNum);

                File file=new File(outFileStr.toString()+".zip");
                if(file.exists()){
                    file.delete();
                }

                ZipUtil.zipFile(fileUrl,outFileStr.toString()+".zip");

            }else if(!durableFileList.isEmpty() && durableFileList.size() > 1){

                ArchivesDurableFile durableFile0=durableFileList.get(0);
                String numStart=durableFile0.getFileUrl().substring(durableFile0.getFileUrl().lastIndexOf("/")+1);
                ArchivesDurableFile durableFileLast=durableFileList.get(durableFileList.size()-1);
                String endStart=durableFileLast.getFileUrl().substring(durableFileLast.getFileUrl().lastIndexOf("/")+1);

                outFileStr.append(numStart)
                        .append("-")
                        .append(endStart);

                File file=new File(outFileStr.toString());
                if (!file.isDirectory()) file.mkdirs();

                for(ArchivesDurableFile durableFile:durableFileList){

                    StringBuilder str=new StringBuilder(tempPath);
                    String num=durableFile.getFileUrl().substring(durableFile.getFileUrl().lastIndexOf("/")+1);

                    str.append(num)
                            .append(".zip");

                    ZipUtil.zipFile(durableFile.getFileUrl(),str.toString());

                    FileUtils.copyFile(new File(str.toString()), new File(outFileStr.toString()+"/"+num+".zip"));
                }
                ZipUtil.zipFile(outFileStr.toString(),outFileStr+".zip");
            }else{
                //throw new BaseException("文件不存在");
            }
            outFileStr.append(".zip");

            //System.out.println("outFileStr:"+outFileStr);

            ServletOutputStream out = null;
            FileInputStream ips = null;
            //获取文件存放的路径
            File file = new File(outFileStr.toString());
            String fileName=file.getName();
            if(!file.exists()) {
                //如果文件不存在就跳出
                return;
            }
            ips = new FileInputStream(file);
            response.setContentType("multipart/form-data");
            //为文件重新设置名字，采用数据库内存储的文件名称
            response.addHeader("Content-Disposition", "attachment; filename=\"" + new String(fileName.getBytes("UTF-8"),"ISO8859-1") + "\"");
            out = response.getOutputStream();
            //读取文件流
            int len = 0;
            byte[] buffer2 = new byte[1024 * 10];
            while ((len = ips.read(buffer2)) != -1){
                out.write(buffer2,0,len);
            }
            out.flush();

        } catch (IOException ex) {
            ex.printStackTrace();
        }

    }


    @ApiOperation(value = "件列表", notes = "")
    @GetMapping("/review/doc")
    public Result<ArchivesList> list(@ApiParam("") @RequestParam(value = "pageNum", required = false) Integer pageNum,
                                     @ApiParam("") @RequestParam(value = "pageSize", required = false) Integer pageSize,
                                     @ApiParam("") @RequestParam(value = "fondsId", required = false) String fondsId,
                                     @ApiParam("") @RequestParam(value = "typeId", required = false) String typeId,
                                     @ApiParam("") @RequestParam(value = "classId", required = false) String classId,
                                     @ApiParam("") @RequestParam(value = "dossierId", required = false) String dossierId,
                                     @ApiParam("条件") @RequestParam(value = "condition", required = false) String condition,
                                     @ApiParam("关键词") @RequestParam(value = "keywords", required = false) String keywords,
                                     @ApiParam("部门") @RequestParam(value = "deptId", required = false) String deptId) {

        ArchivesSearch as = ArchivesSearch.builder().fondsId(fondsId).typeId(typeId).classId(classId)
                .condition(condition)
                .keywords(keywords)
                .fileType(DicDocFileType.DOC.getKey())
                .deptId(deptId)
                .state(DicDocState.approval.getKey())
                .isDelete(BaseConstants.DELETE_NORMAL)
                .dossierId(dossierId)
                .build();


        return docService.list(pageNum, pageSize,as);
    }

    @ApiOperation(value = "卷列表", notes = "")
    @GetMapping("/review/dossier")
    public Result<ArchivesList> list1(@ApiParam("") @RequestParam(value = "pageNum", required = false) Integer pageNum,
                                      @ApiParam("") @RequestParam(value = "pageSize", required = false) Integer pageSize,
                                      @ApiParam("") @RequestParam(value = "fondsId", required = false) String fondsId,
                                      @ApiParam("") @RequestParam(value = "typeId", required = false) String typeId,
                                      @ApiParam("") @RequestParam(value = "classId", required = false) String classId,
                                      @ApiParam("条件") @RequestParam(value = "condition", required = false) String condition,
                                      @ApiParam("关键词") @RequestParam(value = "keywords", required = false) String keywords,
                                      @ApiParam("部门") @RequestParam(value = "deptId", required = false) String deptId) {


        ArchivesSearch as = ArchivesSearch.builder().fondsId(fondsId).typeId(typeId).classId(classId)
                .condition(condition)
                .keywords(keywords)
                .fileType(DicDocFileType.DOSSIER.getKey())
                .deptId(deptId)
                .state(DicDocState.approval.getKey())
                .isDelete(BaseConstants.DELETE_NORMAL)
                .dossierId("0")
                .build();


        return docService.list(pageNum, pageSize,as);
    }

//    @ApiOperation(value = "统计待归档审批件数", notes = "")
//    @GetMapping("/review/statistics")
//    public Result<Integer> list1(@ApiParam("门类号") @RequestParam(value = "extType", required = false) String extType,
//                                 @ApiParam("全宗号") @RequestParam(value = "fondsNum", required = false) String fondsNum,
//                                 @ApiParam("分类号") @RequestParam(value = "classNum", required = false) String classNum,
//                                 @ApiParam("0件 1卷") @RequestParam(value = "model", required = false) String model) {
//
//        if (StringUtils.isEmpty(fondsNum) || StringUtils.isEmpty(extType)) {
//            return ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "全宗号或门类号不能为空", null);
//        }
//        QueryWrapper<ArchivesDoc> queryWrapper = new QueryWrapper<ArchivesDoc>();
//        queryWrapper.eq("fondsNum", fondsNum);
//        queryWrapper.eq("typeNum", extType);
//        if (!StringUtils.isEmpty(classNum)) {
//            queryWrapper.eq("classNum", classNum);
//        }
//        queryWrapper.eq("fileType", "0".equals(model) ? "doc" : "dossier");
//        queryWrapper.eq("state", "1");
//        queryWrapper.select("id");
//        Integer count = archivesDocMapper.selectCount(queryWrapper);
//        return ResultUtil.data(ResultCode.RESULT_SUCCESS.getCode(), "", count == null ? 0 : count);
//    }

    @ApiOperation(value = "归档审批通过", notes = "")
    @PostMapping("/review/pass")
    @Transactional(rollbackFor = Exception.class)
    @LoginAuth()
    public Result<String> pass(@ApiIgnore @LoginUser UserInfo loginUser, @RequestBody SetStateParam setStateParam,HttpServletRequest request) {
        //try {
            List<String> ids = setStateParam.getIds();

            ArchivesType at = null;
            if (org.apache.commons.lang3.StringUtils.isNotEmpty(setStateParam.getTypeId())) {
                at = archivesTypeMapper.selectById(Long.parseLong(setStateParam.getTypeId()));
                if (null == at) return ResultUtil.error( "门类不正确");
            }
            if(StringUtils.isEmpty(setStateParam.getClassId())){
                QueryWrapper<ArchivesDoc> wrapper = new QueryWrapper<ArchivesDoc>();
                wrapper.select("distinct classId");
                wrapper.eq("typeId",setStateParam.getTypeId());
                wrapper.eq("fondsId",setStateParam.getFondsId());
                wrapper.in("id",ids);
                List<ArchivesDoc> classIds= archivesDocMapper.selectList(wrapper);//获取ids下包含的classId
                Map<String,List<String>> map=new HashMap<>();
                for (int i=0;i<classIds.size();i++){
                    if(classIds.get(i)==null){
                        continue;
                    }
                    String classId=classIds.get(i).getClassId().toString();
                    wrapper = new QueryWrapper<ArchivesDoc>();
                    wrapper.select("id");
                    wrapper.eq("typeId",setStateParam.getTypeId());
                    wrapper.eq("fondsId",setStateParam.getFondsId());
                    wrapper.eq("classId",classId);
                    wrapper.in("id",ids);
                    List<ArchivesDoc> docListId= archivesDocMapper.selectList(wrapper);//获取对应classId的docId集合
                    List<String> listId=new ArrayList<>();
                    for(int j=0;j<docListId.size();j++){
                        String id=docListId.get(j).getId().toString();
                        listId.add(id);
                    }
                    map.put(classId,listId);
                }
                if(map.isEmpty()){
                    Result str= archivesService.automationDossierItemNumNum(at,setStateParam.getType(),null,setStateParam.getFondsId(),ids);
                    if("1001".equals(str.getCode())){
                        return str;
                    }
                }else {
                    //遍历集合对与classId对应的ids进行件号卷号的生成
                    for (Map.Entry<String, List<String>> entry : map.entrySet()) {
                        Result str= archivesService.automationDossierItemNumNum(at,setStateParam.getType(),entry.getKey(),setStateParam.getFondsId(),entry.getValue());
                        if("1001".equals(str.getCode())){
                            return str;
                        }
                    }
                }


            }else{
                Result str= archivesService.automationDossierItemNumNum(at,setStateParam.getType(),setStateParam.getClassId(),setStateParam.getFondsId(),ids);
                if("1001".equals(str.getCode())){
                    return str;
                }
            }


            ArchivesDoc entity = new ArchivesDoc();
            entity.setSysArchivingTime(DateUtil.getCurrentTime());
            if ("doc".equals(setStateParam.getType())) {
                entity.setState("2");
                QueryWrapper<ArchivesDoc> updateWrapper = new QueryWrapper<ArchivesDoc>();
                updateWrapper.in("id", ids);
                archivesDocMapper.update(entity, updateWrapper);
            } else if ("dossier".equals(setStateParam.getType())) {
                entity.setState("2");

                UpdateWrapper<ArchivesDoc> updateWrapper = new UpdateWrapper<ArchivesDoc>();
                updateWrapper.in("id", ids);
                archivesDocMapper.update(entity, updateWrapper);

                UpdateWrapper<ArchivesDoc> updateWrapperDoc = new UpdateWrapper<ArchivesDoc>();
                updateWrapperDoc.in("dossierId", ids);
                ArchivesDoc docEntity = new ArchivesDoc();
                docEntity.setState("2");
                docEntity.setSysArchivingTime(DateUtil.getCurrentTime());
                archivesDocMapper.update(docEntity, updateWrapperDoc);
            } else {
                return ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "参数异常", "");
            }

            //添加行为描述
            archivesBehaveLogService.saveArchivesBehaveLog(new ArchivesBehaveLog(BaseUtil.listToString(ids), BehaveLogType.ADD_ARCHIVIST.getKey(),BehaveLogType.ADD_ARCHIVIST.getValue(),"从档案整理添加到档案保存"),loginUser ,request);


            //生成持久化保存文件
            if (RedisUtil.isAppoint(VersionsMarkType.VERSIONS_5) && at.getAutoDurableFile().equals("1")) {
                String docTotalSize = archivesService.saveArchivesDurableFile(ids,setStateParam.getFondsId(),setStateParam.getTypeId(),setStateParam.getClassId(),setStateParam.getType());
                archivesService.createArchivesXml(ids,setStateParam.getType(),loginUser.getId(),request,docTotalSize);
            }

            //加入检索库
            if (RedisUtil.isAppoint(VersionsMarkType.VERSIONS_5)) {
                archivesService.addArticle(ids);
            }


            return ResultUtil.data(ResultCode.RESULT_SUCCESS.getCode(), "", "");
        //} catch (Exception e) {
        //    e.printStackTrace();
            //return ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "", null);
        //}
    }

    @ApiOperation(value = "审批打回", notes = "")
    @PostMapping("/review/reject")
    @Transactional(rollbackFor = Exception.class)
    @LoginAuth()
    public Result<String> reject(@ApiIgnore @LoginUser UserInfo loginUser,@RequestBody SetStateParam setStateParam,HttpServletRequest request) {
        try {
            List<String> ids = setStateParam.getIds();
            for (String string : ids) {
                ArchivesDoc entity = new ArchivesDoc();
                if ("doc".equals(setStateParam.getType())) {
                    entity.setId(Long.parseLong(string));
                    entity.setState("0");
                    archivesDocMapper.updateById(entity);
                } else if ("dossier".equals(setStateParam.getType())) {
                    entity.setId(Long.parseLong(string));
                    entity.setState("0");
                    int update = archivesDocMapper.updateById(entity);
                    if (update <= 0) {
                        throw new Exception();
                    }
                    UpdateWrapper<ArchivesDoc> updateWrapper = new UpdateWrapper<ArchivesDoc>();
                    updateWrapper.in("dossierId", ids);
                    ArchivesDoc docEntity = new ArchivesDoc();
                    docEntity.setState("0");
                    archivesDocMapper.update(docEntity, updateWrapper);
                }
            }

            archivesBehaveLogService.saveArchivesBehaveLog(new ArchivesBehaveLog(BaseUtil.listToString(ids),BehaveLogType.SEND_BACK_SJ.getKey(),BehaveLogType.SEND_BACK_SJ.getValue(),"从档案整理打回到档案收集"),loginUser ,request);

            return ResultUtil.data(ResultCode.RESULT_SUCCESS.getCode(), "", "");
        } catch (Exception e) {
            return ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "", "");
        }
    }

    @ApiOperation(value = "打回整编", notes = "")
    @PostMapping("/review/reorganization")
    @Transactional(rollbackFor = Exception.class)
    @LoginAuth()
    public Result<String> reorganization(@ApiIgnore @LoginUser UserInfo loginUser,@RequestBody SetStateParam setStateParam,HttpServletRequest request) {
        try {
            List<String> ids = setStateParam.getIds();
            List<ArchivesDoc> docIds = new ArrayList<>();
            List<ArchivesDoc> dossierIds = new ArrayList<>();
            for (String string : ids) {
                ArchivesDoc entity = new ArchivesDoc();
                entity.setSysArchivingTime("");
                if ("doc".equals(setStateParam.getType())) {
                    entity.setId(Long.parseLong(string));
                    entity.setState("1");
                    docIds.add(entity);
                    archivesDocMapper.updateById(entity);
                } else if ("dossier".equals(setStateParam.getType())) {
                    entity.setId(Long.parseLong(string));
                    entity.setState("1");
                    int update = archivesDocMapper.updateById(entity);
                    dossierIds.add(entity);
                    if (update <= 0) {
                        throw new Exception();
                    }
                    UpdateWrapper<ArchivesDoc> updateWrapper = new UpdateWrapper<ArchivesDoc>();
                    updateWrapper.eq("dossierId", string);
                    ArchivesDoc docEntity = new ArchivesDoc();
                    docEntity.setState("1");
                    docEntity.setSysArchivingTime("");
                    archivesDocMapper.update(docEntity, updateWrapper);
                }
            }

            //删除持久化文件
            ArchivesType at = archivesTypeMapper.selectById(Long.parseLong(setStateParam.getTypeId()));
            if("1".equals(at.getAutoDurableFile())){
                QueryWrapper<ArchivesDurableFile> queryWrapper=new QueryWrapper<>();
                queryWrapper.in("docId",ids);
                List<ArchivesDurableFile> durableFileList = archivesDurableFileMapper.selectList(queryWrapper);
                for(ArchivesDurableFile durableFile:durableFileList){
                    File file=new File(durableFile.getFileUrl());
                    FileBaseUtil.delete(file);
                }
                archivesDurableFileMapper.delete(queryWrapper);
            }


            archivesBehaveLogService.saveArchivesBehaveLog(new ArchivesBehaveLog(BaseUtil.listToString(ids),BehaveLogType.SEND_BACK_ZB.getKey(),BehaveLogType.SEND_BACK_ZB.getValue(),"从档案保存打回到档案整理"),loginUser ,request);


            return ResultUtil.data(ResultCode.RESULT_SUCCESS.getCode(), "", "");
        } catch (Exception e) {
            //e.printStackTrace();
            return ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "", "");
        }
    }
}
